﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Lucene.Net.Documents;
using NLog;

namespace TfsGiggle.Core
{
    /// <summary>
    /// Packs up documents for transfer over the wire
    /// </summary>
    internal static class QueryResult
    {
        static Logger _logger = LogManager.GetCurrentClassLogger();

        /// <summary>
        /// Packs a dto for the query result
        /// </summary>
        /// <param name="documentList"></param>
        /// <returns></returns>
        internal static QueryResultDTO GetQueryResultDTO(IEnumerable<Document> documentList)
        {
            _logger.Trace("enter");

            var timer = new Stopwatch();
            timer.Start();
            var changesets = new Dictionary<int, TfsGiggleChangeset>();
            var workitems = new Dictionary<int, TfsGiggleWorkitem>();
            var files = new Dictionary<int, TfsGiggleFile>();

            var queryResultDTO = new QueryResultDTO();
            foreach (var document in documentList)
            {
                var documentKeys = document.GetValues(SourceControlDocument.FieldNames.DocumentKey);
                if (documentKeys == null || documentKeys.Length != 1)
                {
                    _logger.Warn("Document has no or too many documentKeys specified");
                }
                var teamProjectCollectionId = IndexModel.GetTeamProjectCollectionIdFromDocumentKey(documentKeys[0]);
                var filePath = IndexModel.GetPathFromDocumentKey(documentKeys[0]);

                var changesetIds = document.GetValues(SourceControlDocument.FieldNames.ChangesetId);
                var changesetComments = document.GetValues(SourceControlDocument.FieldNames.ChangesetComment);
                var changesetComitters = document.GetValues(SourceControlDocument.FieldNames.ChangesetCommitter);
                if (changesetIds != null && changesetIds.Length > 0 &&
                    changesetComments != null && changesetComments.Length > 0 &&
                    changesetComitters != null && changesetComitters.Length > 0 &&
                    changesetIds.Length == changesetComments.Length && changesetIds.Length == changesetComitters.Length)
                {
                    for (int i = 0; i < changesetIds.Length; i++)
                    {
                        var changeset = new TfsGiggleChangeset() { Id = int.Parse(changesetIds[i]), Committer = changesetComitters[i], Comment = changesetComments[i], TeamProjectCollectionId = teamProjectCollectionId };
                        if (!changesets.ContainsKey(changeset.GetHashCode()))
                        {
                            changesets.Add(changeset.GetHashCode(), changeset);
                        }
                    }
                    _logger.Trace("{0} changesets found for {1}", changesetIds.Length, filePath);
                }
                var workItemIds = document.GetValues(SourceControlDocument.FieldNames.WorkitemId);
                var workItemTitles = document.GetValues(SourceControlDocument.FieldNames.WorkitemTitle);
                if (workItemIds != null && workItemIds.Length > 0 &&
                    workItemTitles != null && workItemTitles.Length > 0 &&
                    workItemIds.Length == workItemTitles.Length)
                {
                    for (int i = 0; i < workItemIds.Length; i++)
                    {
                        var workItem = new TfsGiggleWorkitem() { Id = int.Parse(workItemIds[i]), Title = workItemTitles[i], TeamProjectCollectionId = teamProjectCollectionId };
                        if (!workitems.ContainsKey(workItem.GetHashCode()))
                        {
                            workitems.Add(workItem.GetHashCode(), workItem);
                        }
                    }
                    _logger.Trace("{0} workitems found for {1}", workItemIds.Length, filePath);
                }
                var file = new TfsGiggleFile() { Name = filePath, TeamProjectCollectionId = teamProjectCollectionId, NumberOfChangesets = changesets.Count, NumberOfWorkitems = workitems.Count };
                if (!files.ContainsKey(file.GetHashCode()))
                {
                    files.Add(file.GetHashCode(), file);
                }
            }
            // Pack the files, changesets ad workitems into the dto
            queryResultDTO.Files = (from p in files select p.Value).ToArray();
            queryResultDTO.Changesets = (from p in changesets select p.Value).ToArray();
            queryResultDTO.Workitems = (from p in workitems select p.Value).ToArray();

            timer.Stop();
            queryResultDTO.GetQueryResultDTOProcessingTimeInTicks = timer.ElapsedTicks;

            return queryResultDTO;
        }
    }
}
